home *** CD-ROM | disk | FTP | other *** search
/ Delphi Magazine Collection 2001 / Delphi Magazine Collection 20001 (2001).iso / DISKS / Issue67 / System / DIPSLIB / DIPSLIB.C < prev    next >
Encoding:
C/C++ Source or Header  |  2001-02-06  |  5.9 KB  |  188 lines

  1. /************************************************************
  2. Module name:    DIPSLib.c
  3. Notices:        Copyright (c) 1996 Jeffrey Richter
  4. Change Log:     Assorted changes by Dave Jewell for Delphi 
  5. ************************************************************/
  6.  
  7. #include "CmnHdr.H" 
  8. #include <Windows.H>
  9. #include <WindowsX.H>
  10. #include <CommCtrl.H>
  11. #include "Resource.H"
  12.  
  13. HINSTANCE g_hinstDll = NULL;
  14.  
  15. //--------------------------------------------------------------------------
  16. // This segment is shared by all applications that use the DLL
  17. //--------------------------------------------------------------------------
  18.  
  19. #pragma data_seg("Shared")
  20. HHOOK hHook = NULL;
  21. DWORD dwApplicationThread = 0;              // thread ID of application which called SetDIPSHook
  22. char szSharedBuff [256];
  23.  
  24.  
  25.  
  26. static const TCHAR g_szRegSubKey[] = __TEXT ("Software\\Richter\\Desktop Item Position Saver");
  27.  
  28. #pragma data_seg()
  29. #pragma comment(linker, "/section:Shared,rws")
  30.  
  31. //--------------------------------------------------------------------------
  32.  
  33. void SaveListViewItemPositions(HWND hwndLV) 
  34. {
  35.    int nItem, nMaxItems = ListView_GetItemCount(hwndLV);
  36.    HKEY hkey;
  37.    DWORD dwDisposition;
  38.  
  39.    // When saving new positions, delete the old position 
  40.    // information that is currently in the registry.
  41.    RegDeleteKey (HKEY_CURRENT_USER, g_szRegSubKey);
  42.  
  43.    // Create the registry key to hold the info
  44.    RegCreateKeyEx (HKEY_CURRENT_USER, g_szRegSubKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_SET_VALUE, NULL, &hkey, &dwDisposition);
  45.  
  46.    for (nItem = 0; nItem < nMaxItems; nItem++) 
  47.    {
  48.       TCHAR szName[_MAX_PATH];
  49.       POINT pt;
  50.  
  51.       // Get the name and position of a listview item.
  52.       ListView_GetItemText (hwndLV, nItem, 0, szName, chDIMOF(szName));
  53.       ListView_GetItemPosition (hwndLV, nItem, &pt);
  54.  
  55.       // Save the name and position in the registry.
  56.       RegSetValueEx (hkey, szName, 0, REG_BINARY, (PBYTE) &pt, sizeof(pt));
  57.    }
  58.  
  59.    RegCloseKey(hkey);
  60. }
  61.  
  62. //--------------------------------------------------------------------------
  63.  
  64. void RestoreListViewItemPositions (HWND hwndLV) 
  65. {
  66.    HKEY hkey;
  67.    LONG l = RegOpenKeyEx(HKEY_CURRENT_USER, g_szRegSubKey,
  68.       0, KEY_QUERY_VALUE, &hkey);
  69.    if (l == ERROR_SUCCESS) {
  70.       int nIndex;
  71.  
  72.       // If the listview has AutoArrange on, 
  73.       // temporarily turn it off.
  74.       DWORD dwStyle = GetWindowStyle (hwndLV);
  75.       if (dwStyle & LVS_AUTOARRANGE) SetWindowLong (hwndLV, GWL_STYLE, dwStyle & ~LVS_AUTOARRANGE);
  76.  
  77.       l = NO_ERROR;
  78.       for (nIndex = 0; l != ERROR_NO_MORE_ITEMS; nIndex++) {
  79.          TCHAR szName[_MAX_PATH];
  80.          POINT pt;
  81.          LV_FINDINFO lvfi;
  82.          int cbValueName = chDIMOF(szName);
  83.          int cbData = sizeof(pt), nItem;
  84.          DWORD dwType;
  85.  
  86.          // Read a value name and position from the registry.
  87.          l = RegEnumValue(hkey, nIndex, szName, &cbValueName, 
  88.             NULL, &dwType, (PBYTE) &pt, &cbData);
  89.  
  90.          if (l == ERROR_NO_MORE_ITEMS) 
  91.             continue;
  92.  
  93.          if ((dwType == REG_BINARY) && (cbData == sizeof(pt))) {
  94.             // The value is something that we recognize; try to find
  95.             // an item in the listview control that matches the name.
  96.             lvfi.flags = LVFI_STRING; 
  97.             lvfi.psz = szName; 
  98.             nItem = ListView_FindItem(hwndLV, -1, &lvfi);
  99.             if (nItem != -1) ListView_SetItemPosition(hwndLV, nItem, pt.x, pt.y);    
  100.          }
  101.       }
  102.       // Turn AutoArrange back on if it was originally on.
  103.       SetWindowLong(hwndLV, GWL_STYLE, dwStyle);
  104.       RegCloseKey(hkey);
  105.    }
  106. }
  107.  
  108. //--------------------------------------------------------------------------
  109.  
  110. BOOL WINAPI DllMain (HINSTANCE hinstDll, DWORD fdwReason, LPVOID fImpLoad) 
  111. {
  112.     if (fdwReason == DLL_PROCESS_ATTACH) g_hinstDll = hinstDll;
  113.     return (TRUE);
  114. }
  115.  
  116. //--------------------------------------------------------------------------
  117.  
  118. void DIPS_OnClose (HWND hwnd)
  119. {
  120.     DestroyWindow (hwnd);
  121. }
  122.  
  123. BOOL WINAPI DIPS_DlgProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) 
  124. {
  125.     switch (uMsg) 
  126.     {
  127.         case WM_APP:
  128.             if (lParam) SaveListViewItemPositions((HWND) wParam);
  129.             else RestoreListViewItemPositions((HWND) wParam);
  130.             break;
  131.  
  132.         chHANDLE_DLGMSG (hwnd, WM_CLOSE, DIPS_OnClose);
  133.     }
  134.    
  135.     return (FALSE);
  136. }
  137.  
  138. //--------------------------------------------------------------------------
  139.  
  140. LRESULT WINAPI GetMsgProc (int nCode, WPARAM wParam, LPARAM lParam) 
  141. {
  142.    static BOOL fFirstTime = TRUE;
  143.  
  144.    if (fFirstTime) 
  145.    {
  146.       fFirstTime = FALSE;
  147.       // Create the server window to service client requests
  148.       CreateDialog (g_hinstDll, MAKEINTRESOURCE (IDD_DIPS), NULL, DIPS_DlgProc);
  149.       // Tell the original application that server is ready
  150.       PostThreadMessage (dwApplicationThread, WM_NULL, 0, 0);
  151.    }
  152.  
  153.    return (CallNextHookEx (hHook, nCode, wParam, lParam));
  154. }
  155.  
  156. //--------------------------------------------------------------------------
  157.  
  158. __declspec (dllexport) BOOL WINAPI SetDIPSHook(DWORD dwThreadId) 
  159. {
  160.    BOOL fOk = FALSE;
  161.    
  162.    if (dwThreadId != 0) 
  163.    {
  164.       // Save our thread ID in a shared variable so that
  165.       // our GetMsgProc function can post a message back to
  166.       // to thread when the server window has been created.
  167.       dwApplicationThread = GetCurrentThreadId();
  168.  
  169.       // Install the hook on the specified thread
  170.       hHook = SetWindowsHookEx(WH_GETMESSAGE, GetMsgProc, g_hinstDll, dwThreadId);
  171.       fOk = (hHook != NULL);
  172.       if (fOk) {
  173.          // The hook was installed successfully; force a
  174.          // benign message to the thread's queue so that 
  175.          // the hook function gets called.
  176.          fOk = PostThreadMessage(dwThreadId, WM_NULL, 0, 0);
  177.       }
  178.    } 
  179.    else 
  180.    {
  181.       fOk = UnhookWindowsHookEx(hHook);
  182.       hHook = NULL;
  183.    }
  184.  
  185.    return(fOk);
  186. }
  187.  
  188.